home *** CD-ROM | disk | FTP | other *** search
-
- ---------------------------------------------------
- ------- Immortal Descandants CrackMe 5.0 ----------
- ------- by TORN@DO, tutorial by Lucifer48 ---------
- ---------------------------------------------------
-
- I apologize for my english, i'am french ;) This translation was difficult.
- (i'am looking for a dictionnary... mail me the url, if you know one!)
- Nice read!
-
- =========================================
- 1. INTRODUCTION - PART 1/2 - NAME OF FILE
- =========================================
-
- It is the first thing to know. I have two solutions:
-
- The first (the more simple) is using filemon:
- we obtain the following result:
-
- 197 20:13:44 Idcrkme5 Open C:\REGISTRATION.DAT NOTFOUND OPENEXISTING OPENALWAYS
- 198 20:13:44 Idcrkme5 Open C:\REGISTRATION.DAT NOTFOUND OPENEXISTING OPENALWAYS
-
- Another (better) method, which will allow us to get the name and enter in the code.
- Into soft-ice, i put a BPX CreateFileA, we are here:
-
- XXXX:00409B1B PUSH EAX ;80000000 (GENERIC_READ)
- XXXX:00409B1C MOV EBP,[KERNEL32!CreateFileA]
- XXXX:00409B22 PUSH ECX ;REGISTRATION.DAT
- XXXX:00409B23 CALL EBP ;CALL [KERNEL32!CreateFileA]
- XXXX:00409B25 CMP EAX,-01 ;EAX=-1 : file not found
- XXXX:00409B28 MOV EBP,EAX ;handle of file
- XXXX:00409B2A JNZ 00409B48
-
- So, i create the file REGISTRATION.DAT, and we can continue in 00409B48.
-
- =============================================
- 2. INTRODUCTION - PART 2/2 - LOST IN THE CODE
- =============================================
-
- XXXX:00409B48 PUSH EBP ;save handle of file
- XXXX:00409B49 CALL [KERNEL32!GetFileType]
- XXXX:00409B4F TEST EAX,EAX
- XXXX:00409B51 JNZ 00409B76
- XXXX:00409B53 PUSH EBP ;handle of file
- XXXX:00409B54 CALL [KERNEL32!CloseHandle] ;close the file
- ...it is not the right way, to succeed in this crackme, we must escape KERNEL32!CloseHandle
-
- Then, we are in a call (where, i don't know), somewhere in vc++ compiled code, the crackme
- does something (well it's not important for the moment). After "few ^p ret" (F12 key),
- everything appears clearly:
-
-
- XXXX:00401ABE PUSH 0040D724 ;datas
- XXXX:00401AC3 PUSH ECX
- XXXX:00401AC4 CALL 004053C0 ;we exit from here
- XXXX:00401AC9 ADD ESP,08 ;pop-pop
- XXXX:00401ACC MOV ESI,EAX
- XXXX:00401ACE TEST ESI,ESI ;if REGISTRATION.DAT don't exist ESI=0
- XXXX:00401AD0 JZ 00401B76 ;going to 00401B76 isn't a good idea
-
- [...]
- few lines... read the keyfile; etc. etc.
- [...]
-
- XXXX:00401B6A XOR EAX,EAX ;here, we are in a wrong way
- XXXX:00401B6C POP EDI
- XXXX:00401B6D POP ESI
- XXXX:00401B6E POP EBX
- XXXX:00401B6F ADD ESP,00000864 ;wow! pop-pop-...-pop-pop
- XXXX:00401B75 RET
- XXXX:00401B76 MOV EAX,00000001
- XXXX:00401B7B POP EDI
- XXXX:00401B7C POP ESI
- XXXX:00401B7D POP EBX
- XXXX:00401B7E ADD ESP,00000864 ;wow! pop-pop-...-pop-pop
- XXXX:00401B84 RET
-
- We are now in the main procedure (call):
-
- XXXX:00401B92 CALL 00401A30 ;<--- WE WERE HERE
- XXXX:00401B97 ADD ESP,04 :pop-pop
- XXXX:00401B9A PUSH 00
- XXXX:00401B9C CALL 00401340
- XXXX:00401BA1 ADD ESP,04 ;pop-pop
- XXXX:00401BA4 PUSH 00
- ...
- XXXX:00401BFE CALL 00401DC0
- XXXX:00401C03 ADD ESP,04 ;pop-pop
- XXXX:00401C06 TEST EAX,EAX
- XXXX:00401C08 JZ 00401D18 ;we mustn't jump
- XXXX:00401C0E PUSH 00
- XXXX:00401C10 CALL 00401A30
- XXXX:00401C15 ADD ESP,04 ;pop-pop
- XXXX:00401C18 TEST EAX,EAX
- XXXX:00401C1A JZ 00401D18 ;no, no jump :)
- XXXX:00401C20 PUSH 00
- XXXX:00401C22 CALL 00401E90
- ...
- there are 17 call to explore (to see), to arrive at the end, it is always the same thing:
- push 00
- call x
- add esp,04
- test eax,eax
- j(n)z bad_keyfile
- ...
- XXXX:00401CFE CALL 00403190
- XXXX:00401D03 ADD ESP,04
- XXXX:00401D06 TEST EAX,EAX
- XXXX:00401D08 JZ 00401D18 ;no!
- XXXX:00401D0A MOV EAX,[ESP+04]
- XXXX:00401D0E PUSH EAX
- XXXX:00401D0F CALL 004012E0 ;yeah!, we have a good keyfile
- XXXX:00401D14 ADD ESP,04 ;pop-pop
- XXXX:00401D17 RET
- XXXX:00401D18 MOV EAX,[ESP+04]
- XXXX:00401D1C PUSH EAX
- XXXX:00401D1D CALL 00401290 ;our keyfile isn't good!
- XXXX:00401D22 ADD ESP,04 ;pop-pop
- XXXX:00401D25 RET
-
- We know our job, exploring these 17 call (thanks Torn@do) to produce a good keyfile
- It is now that the crackme begins.
-
-
- ================================================
- 3. PART 01/17 - CALL 00401DC0 (en XXXX:00401BFE)
- ================================================
-
- Each call is built is on same way, i won't explain the beginning of the call (check if the
- keyfile exists... etc. etc). Interessing things (made by Torn@do) are located at the end of
- the call. Let's go:
-
- XXXX:00401E56 PUSH EAX ;bytes from our keyfile
- XXXX:00401E57 CALL 00405240 ;length of the keyfile
- XXXX:00401E5C ADD ESP,10
- XXXX:00401E5F MOV EBX,EAX ;EBX = length of keyfile
- ...
- XXXX:00401E6A SUB EBX,00000400 ;400h = 1024d
- XXXX:00401E70 POP EDI
- XXXX:00401E71 POP ESI
- XXXX:00401E72 CMP EBX,01
- XXXX:00401E75 SBB EAX,EAX ;substract 1 if and only if carry (CF=1)
- XXXX:00401E77 POP EBX
- XXXX:00401E78 NEG EAX ;NEG FFFFFFFF = 00000001
- XXXX:00401E7A ADD ESP,00000800
- XXXX:00401E80 RET ;end of call 00401DC0
-
- To bypass this call, we must have a keyfile with a length of 1024 bytes.
-
- Remark: we look (more deeply) at the call which computes the length of the keyfile:
- (example, a keyfile with 4 bytes)
- REGISTRATION.DAT 31 32 33 34 the call 00405240 gives EAX=00000004
- REGISTRATION.DAT 31 1A 33 34 the call 00405240 gives EAX=00000001
- REGISTRATION.DAT 31 0D 0A 34 the call 00405240 gives EAX=00000003
- (each 0D is deleted)
-
- So i create my keyfile with 1024 bytes.
-
- ================
- 4. THE SURPRISE!
- ================
-
- VERSION 1:
- ----------
- I restart the crackme, then...surprise!!! **boom** i receive an error (page fault).
- After few try, i discover that if the keyfile is more than 188 bytes, then we get a page fault,
- otherwise, no error.
- At the beginning, i REALLY thought it was a bug! i mailed Torn@do to ask him, he answered me
- there were no bug.
- I really thought there was a bug, until the moment i decided to locate (to look after) the error.
-
- XXXX:00401B92 CALL 00401A30
- XXXX:00401B97 ADD ESP,04 :pop-pop
- XXXX:00401B9A PUSH 00
- XXXX:00401B9C CALL 00401340 ;PAGE FAULT HERE!
- XXXX:00401BA1 ADD ESP,04 ;pop-pop
-
- In fact, the stack is filled we our keyfile (i saw it later...) and, as i want to bypass this
- call (without error of course), i put the right adress of the call 00401340 (that's 00401BA1)
- in my keyfile. At this moment i tought, it was thought by Torn@do (it's a good idea).
-
- At the end of the call 00401340 (after the instruction add esp,20), if we do a d ESP, we see
- we are "in the middle" of the keyfile (but xor'ed, for me it's 67)
- And: 00401340 XOR 67676767 = 67277427
-
- 000000B0 ?? ?? ?? ?? ?? ?? ?? ??-?? 67 27 74 27 ?? ?? ?? .........g't'...
-
- No more page fault, we continue.
-
- VERSION 2: The version 1 isn't the right method, because the crackme was expected a nul byte
- ---------- (we don't have to put the adress of come back of this call in the keyfile, it is a
- mistake). Read the next chapter, to understand what i mean.
-
-
- ================================================
- 5. PART 02/17 - CALL 00401A30 (en XXXX:00401C10)
- ================================================
-
- At the beginning, i thought this call weren't important, and i discovered that it was the place
- where the name (in the message box "request") was built.
-
- ...
- XXXX:00401B3A NOT ECX
- XXXX:00401B3C DEC ECX ;length of our "name area"
- XXXX:00401B3D XOR BL,CL ;BL is a char from the keyfile
- XXXX:00401B3F MOV ECX,FFFFFFFF
- XXXX:00401B44 SUB EAX,EAX
- XXXX:00401B46 MOV [EDX+0040D186],BL ;save the char xor'ed
- ...
-
- Example with my name, i want to write "Lucifer48"
-
- 00000090 ?? ?? ?? ?? ?? ?? ?? ??-?? p1 p2 p3 p4 p5 p6 p7 ................
- 000000A0 p8 p9 00 ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ................
-
- We MUST put a null byte after this "name area". Each character is xor'ed with the length of the
- name (for me 9). So, Lucifer48 become : 45 7C 6A 60 6F 6C 7B 3D 31.
-
- The byte 00 is very very very important, at the beginning i hadn't put it, and later, the
- crackme use this null byte (REPNZ SCASB). So i experienced (encountered) many probems (with the
- stack) For me, the length of "name area" was 67h!!!
-
- The icon of the crackme (upper left corner) is always the same...
-
- ================================================
- 6. PART 03/17 - CALL 00401E90 (en XXXX:00401C22)
- ================================================
-
- XXXX:00401F47 MOV DL,[EAX+0040D0F0] ;at start: EAX=0
- XXXX:00401F4D CMP [EAX+ESP+38],DL ;compare with a byte in the keyfile
- XXXX:00401F51 JNZ 00401F73 ;if not equal, we exit
- XXXX:00401F53 MOV DWORD PTR [0040D0B4],00000001 ;a new icon!
- XXXX:00401F5D INC CX
- XXXX:00401F5F CMP CX,09
- XXXX:00401F63 JLE 00401F44
- XXXX:00401F65 MOV EAX,00000001 ;if we are here, it is ok.
- ...
- XXXX:00401F72 RET
-
- We put in the keyfile the 10 bytes wanted by the crackme. So:
-
- 00000000 06 0A 15 07 13 10 0A 72-0C 00 ?? ?? ?? ?? ?? ?? .......r........
-
- We finished this call, the icon skeleton's head ;)
-
- ================================================
- 7. PART 04/17 - CALL 00401F80 (en XXXX:00401C34)
- ================================================
-
- We must exit the call with EAX=0
-
- XXXX:0040210C MOV DWORD PTR [0040D0B4],00000002 ;still a new icon
- XXXX:00402116 XOR EAX,EAX
- XXXX:00402118 POP EBP
- XXXX:00402119 POP EDI
- XXXX:0040211A POP ESI
- XXXX:0040211B POP EBX
- XXXX:0040211C ADD ESP,00000800
- XXXX:00402122 RET ;end of call 00401F80
-
- Before, few 'xor' with a part of our keyfile, it's very easy to understand.
- To get eax=0, we must validate few comparasions:
- (CMP BL,53 / CMP EAX,6F / CMP ECX,66 / CMP EDX,70 / CMP ESI,49 / CMP EDI,43 / CMP EBP,45)
- In the keyfile:
-
- 00000000 ** ** ** ** ** ** ** **-** ** 07 20 34 3E 09 07 ........... 4>..
- 00000010 0A ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ................
-
- Remark: if you haven't understand yet, "**" means that this byte is already known (found)
- in a previous call (see above), and the "??" is a unknown byte.
-
- The new icon is a cross!
-
-
- ================================================
- 8. PART 05/17 - CALL 00402130 (en XXXX:00401C46)
- ================================================
-
- We must exit the call with EAX=1.
-
- XXXX:00402241 MOV DWORD PTR [0040D0B4],00000003 ;a new icon
- XXXX:0040224B MOV EAX,00000001
- XXXX:00402250 POP EBP
- XXXX:00402251 POP EDI
- XXXX:00402252 POP ESI
- XXXX:00402253 POP EBX
- XXXX:00402254 ADD ESP,00000800
- XXXX:0040225A RET ;end of call 00402130
-
- There is four comparasions:
-
- XXXX:004021DA MOVSX ESI,BYTE PTR [ESP+55] ;(cmp ESI,08)
- XXXX:004021DF MOVSX EDI,BYTE PTR [ESP+56] ;(test EDI,EDI)
- XXXX:004021E4 MOVSX EBX,BYTE PTR [ESP+57] ;(test EBX,EBX)
- XXXX:004021E9 MOVSX EBP,BYTE PTR [ESP+58] ;(cmp EBP,05)
-
- Finaly:
- 00000010 ** 08 00 00 05 ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ................
-
-
- ================================================
- 9. PART 06/17 - CALL 00402260 (en XXXX:00401C58)
- ================================================
-
- The good way:
-
- XXXX:00402597 MOV DWORD PTR [0040D0B4],00000004 ;new icon
- XXXX:004025A1 XOR EAX,EAX
- XXXX:004025A3 POP EBP
- XXXX:004025A4 POP EDI
- XXXX:004025A5 POP ESI
- XXXX:004025A6 POP EBX
- XXXX:004025A7 ADD ESP,00000834
- XXXX:004025AD RET ;end of call 00402260
-
- There are 17 new bytes to find. Let introduce b0, b1b ..bG the 17 bytes to find.
- The crackme is expecting for:
-
- b0 OR 56 ebx =5E | b9 OR 53 [esp+24] =7F
- b1 OR 49 [esp+10] =4D | bA OR 20 [esp+28] =63
- b2 OR 53 [esp+14] =53 | bB OR 53 [esp+2C] =5B
- b3 OR 49 ebp =5B | bC OR 49 [esp+30] =4B
- b4 OR 54 esi =5E | bD OR 54 [esp+34] =7E
- b5 OR 20 edi =32 | bE OR 45 [esp+38] =4F
- b6 OR 54 [esp+18] =57 | bF OR 21 [esp+40] =65
- b7 OR 48 [esp+1C] =5A | bG OR 21 [esp+44] =75
- b8 OR 49 [esp+20] =4B |
-
- In these cases, there are few good possibilities, i will choose one:
- (result XOR mask)
-
- Result in the keyfile:
-
- 00000010 ** ** ** ** ** 08 04 00-12 0A 12 03 12 02 2C 43 ..............,C
- 00000020 08 02 2A 0A 44 54 ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ..*.DT..........
-
-
- =================================================
- 10. PART 07/17 - CALL 004025B0 (en XXXX:00401C6A)
- =================================================
-
- The call uses the four following bytes:
-
- 00000050 X1 X2 X3 X4 ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ................
-
-
- XXXX:004026EB CMP DWORD PTR [0040EA98],04 ;DWORD PTR [0040EA98] = 000000X2
- XXXX:004026F2 MOV [0040EA9C],EAX
- XXXX:004026F7 JAE 0040271A
-
- Then, a call GetLocalTime (uses the year). It makes a sort of sum (a checksum) with these four
- bytes. And compares it with 1999; i have not understand everything ;) Then:
-
- XXXX:00402751 MOV DWORD PTR [0040D0B4],00000005 ;nouvelle icone
- XXXX:0040275B XOR EAX,EAX
- ...
- XXXX:00402775 MOV EAX,00000001
- XXXX:0040277A POP EDI
- XXXX:0040277B POP ESI
- XXXX:0040277C ADD ESP,00000814
- XXXX:00402782 RET ;end of call 004025B0
-
- i put X1=X2=X3=X4=FF and it works.
-
-
- ===================================================
- 11. PARTIE 08/17 - CALL 00402790 (en XXXX:00401C7C)
- ===================================================
-
- We must exit with EAX=1, it is very simple:
-
- XXXX:0040283E MOVSX EAX,BYTE PTR [ESP+00000091] ;a char from the keyfile
- XXXX:00402846 MOVSX ECX,BYTE PTR [ESP+00000090] ;another char from the keyfile
- XXXX:0040284E ADD ESP,04
- XXXX:00402851 MOV [0040EA88],EAX
- XXXX:00402856 CMP ECX,17
- XXXX:00402859 JA 00402884 ;bad jump
- XXXX:0040285B CMP EAX,3B
- XXXX:0040285E JA 00402884 ;bad jump
- XXXX:00402860 MOV DWORD PTR [0040D0B4],00000005 ;a new icon
- ...
- XXXX:0040287E MOV EAX,00000001
- XXXX:00402883 RET ;end of call 00402790
-
- In the keyfile:
- 00000050 ** ** ** ** 17 3B ?? ??-?? ?? ?? ?? ?? ?? ?? ?? .....;..........
-
-
- =================================================
- 12. PART 09/17 - CALL 004028A0 (en XXXX:00401C8E)
- =================================================
-
- XXXX:00402952 MOVSX EAX,SI ;SI=0001
- XXXX:00402958 MOV CL,[EAX+0040D0FF] ;datas
- XXXX:0040295E CMP [EAX+ESP+00000107],CL ;compare with a byte in our keyfile
- XXXX:00402965 JNZ 00402987 ;must be equal
- XXXX:00402967 INC SI
- XXXX:00402969 CMP SI,58 ;58h = 88d
- XXXX:0040296D JLE 0040294B ;loop
- XXXX:0040296F MOV DWORD PTR [0040D0B4],00000007 ;new icon
- XXXX:00402979 MOV EAX,00000001
- XXXX:0040297E POP EDI
- XXXX:0040297F POP ESI
- XXXX:00402980 ADD ESP,00000800
- XXXX:00402986 RET ;end of call 004028A0
-
- We add in the keyfile:
-
- 000000D0 53 55 50 50 4F 52 54 20-54 48 45 20 53 4F 46 54 SUPPORT THE SOFT
- 000000E0 57 41 52 45 20 41 55 54-48 4F 52 53 20 42 59 20 WARE AUTHORS BY
- 000000F0 42 55 59 49 4E 47 20 54-48 45 20 50 52 4F 47 52 BUYING THE PROGR
- 00000100 41 4D 53 20 49 46 20 59-4F 55 20 55 53 45 20 54 AMS IF YOU USE T
- 00000110 48 45 4D 20 41 46 54 45-52 20 43 52 41 43 4B 49 HEM AFTER CRACKI
- 00000120 4E 47 20 54 48 45 4D 21-?? ?? ?? ?? ?? ?? ?? ?? NG THEM!........
-
-
- =================================================
- 13. PART 10/17 - CALL 004029A0 (en XXXX:00401C9C)
- =================================================
-
- XXXX:00402A68 MOVSX EAX,SI
- XXXX:00402A6B ADD ESP,04
- XXXX:00402A6E MOV CL,[EAX+0040D1C7] ;datas
- XXXX:00402A74 CMP [EAX+ESP+00000187],CL ;cmp with our keyfile
- XXXX:00402A7B JNZ 00402AAC ;if jump = bad keyfile
- XXXX:00402A7D INC SI
- XXXX:00402A7F MOV EDI,0040D1C8 ;datas, (about box, etc.)
- XXXX:00402A84 MOV ECX,FFFFFFFF
- XXXX:00402A89 SUB EAX,EAX
- XXXX:00402A8B REPNZ SCASB ;string length
- XXXX:00402A8D MOVSX EAX,SI
- XXXX:00402A90 NOT ECX
- XXXX:00402A92 DEC ECX
- XXXX:00402A93 CMP ECX,EAX ;end of loop ?
- XXXX:00402A95 JAE 00402A61
- XXXX:00402A97 MOV DWORD PTR [0040D0B4],00000008 ;new icon
- XXXX:00402AA1 XOR EAX,EAX
- XXXX:00402AA3 POP EDI
- XXXX:00402AA4 POP ESI
- XXXX:00402AA5 ADD ESP,00000800
- XXXX:00402AAB RET ;end of call 004029A0
-
- I add, some new bytes, in my keyfile:
-
- 00000150 36 37 3C 3E 3E 32 54 4A-52 32 35 35 3C 35 3C 3A 67<>>2TJR255<5<;
- 00000160 37 32 3E 37 35 3C 38 ??-?? ?? ?? ?? ?? ?? ?? ?? 72>75<8.........
-
- These datas come directly from:
- [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion]
- "ProductId"="12799-OEM-0070752-92073"
-
-
- =================================================
- 14. PART 11/17 - CALL 00402AC0 (en XXXX:00401CAA)
- =================================================
-
- The job: exit the call with EAX=1.
-
- XXXX:00402B70 MOVSX EAX,CX ;at start CX=1
- XXXX:00402B73 INC CX
- XXXX:00402B75 MOVSX EDX,BYTE PTR [EAX+ESP+3B] ;beginning of the keyfile
- XXXX:00402B7A ADD EBX,EDX
- XXXX:00402B7C CMP CX,64 ;64d = 100d
- XXXX:00402B80 JLE 00402B70 ;loop
- XXXX:00402B82 XOR EBX,000007CF
-
- The (integer) division of ECX by 10 must be equal to the value of a specific byte from our
- keyfile. So EBX div 10 = 255 ( =FF, the maximum, otherwise it is more than 1 byte, so EBX don't
- have to be greater than 0x9FF). See remark below.
-
- I fill my keyfile, to be all right.
-
- XXXX:00402BA2 MOV EAX,EBX ;sum of the 100 first characters
- XXXX:00402BA4 SUB EDX,EDX
- XXXX:00402BA6 DIV ECX ;ECX=0000000A
- XXXX:00402BA8 MOVSX ECX,BYTE PTR [ESP+000003EC]
- XXXX:00402BB0 MOV [0040D1A8]
- XXXX:00402BB5 CMP EAX,ECX ;cmp ZZ,EAX
- XXXX:00402BB7 JZ 00402BC5 ;must be equal!
- ...
- XXXX:00402BC5 MOV DWORD PTR [0040D0B4],00000009 ;new icon
- XXXX:00402BCF MOV EAX,00000001
- XXXX:00402BD4 POP EDI
- XXXX:00402BD5 POP ESI
- XXXX:00402BD6 POP EBX
- XXXX:00402BD7 ADD ESP,00000800
- XXXX:00402BDD RET ;end of call 00402AC0
-
- 000003B0 ZZ ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ................
-
- ZZ= is the result (one byte) of the (integer) division (for me it is ZZ=3B)
-
- Remark: ZZ=00 isn't a interressing value, i won't use it, let's suppose ZZ<>0
- Choose a byte between 10 et 7Fh=127d, because if for example you have ZZ=0xF0 then the instruction
- MOVSX ECX,F0 will have for result: ECX=FFFFFFF0.
- (be carefull MOVSX <> MOVZX) and if ZZ<0xA, we could not continue.
- My advise for choosing ZZ: a smal number!
-
-
- =================================================
- 15. PART 12/17 - CALL 00402BE0 (en XXXX:00401CB8)
- =================================================
-
- We must exit the call with EAX=1, this call is a sort of addon of the previous call.
-
- XXXX:00402CD2 DIV ECX ;ECX=54, do ZZ▓ DIV ECX
- XXXX:00402CD4 MOVSX EDX,BYTE PTR [ESP+000003ED] ;read a char from the keyfile
- XXXX:00402CDC MOV [0040D1AC],EAX ;YY
- XXXX:00402CE1 CMP EDX,EAX ;we must have EAX=EDX
- XXXX:00402CE3 JZ 00402CF1
- ...
- XXXX:00402CF1 MOV DWORD PTR [0040D0B4],0000000A ;new icon, the 10th!
- XXXX:00402CFB MOV EAX,00000001
- XXXX:00402D00 POP EDI
- XXXX:00402D01 POP ESI
- XXXX:00402D02 POP EBX
- XXXX:00402D03 ADD ESP,00000800
- XXXX:00402D09 RET ;end of call 00402BE0
-
- 000003B0 ZZ YY ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ................
-
- YY = ZZ▓ div 54 (YY and ZZ are two bytes, and ZZ>9 (9h*9h=51h) )
-
- Remaque: YY=00 isn't a interressing value, i won't use it, let's suppose YY<>0.
- we must have (ZZ▓ div 54) > YY
-
-
- =================================================
- 16. PART 13/17 - CALL 00402D10 (en XXXX:00401CC6)
- =================================================
-
- XXXX:00402DFD MOVSX ECX,BYTE PTR [EAX+ESP+3B] ;the beginning of the keyfile
- XXXX:00402E02 ADD ESI,ECX ;at start: esi=0
- XXXX:00402E04 INC EAX ;at start: eax=0
- XXXX:00402E05 CMP EAX,00000180 ;180h = 384d
- XXXX:00402E0A JBE 00402DFD ;loop
- XXXX:00402E0C MOV EDI,EAX
- ...
- XXXX:00402E1A IMUL EAX,EDI ;YY*ZZ
- XXXX:00402E1D XOR EAX,ESI ;esi sum of the first 384 chars = SUM
- XXXX:00402E1F MOV ECX,00000216
- XXXX:00402E24 SUB EDX,EDX ;xor edx,edx
- XXXX:00402E26 DIV ECX
- XXXX:00402E28 MOVSX EDX,BYTE PTR [ESP+000003EE]
- XXXX:00402E30 MOV [0040D1B0],EAX ;TT
- XXXX:00402E35 CMP EDX,EAX ;cmp TT,EAX
- XXXX:00402E37 JZ 00402E45
-
- 000003B0 ZZ YY TT ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ................
-
- XXXX:00402E45 MOV DWORD PTR [0040D0B4],0000000B ;still a new icon
- XXXX:00402E4F MOV EAX,00000001
- XXXX:00402E54 POP EDI
- XXXX:00402E55 POP ESI
- XXXX:00402E56 POP EBX
- XXXX:00402E57 ADD ESP,00000800
- XXXX:00402E5D RET ;end of call 00402D10
-
- Remark: if we want TT<>0, we must have:
- ( (YY*ZZ) XOR SUM ) div 216 = TT with TT > YY
-
- The icon is smiling!
-
-
- =================================================
- 17. PART 14/17 - CALL 00402E60 (en XXXX:00401CD4)
- =================================================
-
- This call use the three previous result.
-
- XXXX:00402F07 MOV EAX,[0040D1B0] ;TT
- XXXX:00402F0C MOV ECX,[0040D1AC] ;YY
- XXXX:00402F12 MOV ESI,[0040D1A8] ;ZZ
- ...
- [...]
- ...
- XXXX:00402F38 MOVSX EDX,BYTE PTR [ESP+000003EB]
- XXXX:00402F40 MOV [040D1B4],EAX ;UU
- XXXX:00402F45 CMP EDX,EAX
- XXXX:00402F47 JZ 00402F54
-
- What'is doing [...]?
- We must have: (TT div YY)*(ZZ div YY)*(TT+YY+ZZ) <> 0 ===> TT > YY et ZZ > YY
-
- XXXX:00402F54 MOV DWORD PTR [0040D0B4],0000000C
- XXXX:00402F5E MOV EAX,00000001
- XXXX:00402F63 POP EDI
- XXXX:00402F64 POP ESI
- XXXX:00402F65 ADD ESP,00000800
- XXXX:00402F6B RET ;end of call 00402E60
-
-
- =================================================
- 18. PART 15/17 - CALL 00402F70 (en XXXX:00401CE2)
- =================================================
-
- This call uses the loop "180h" (see above, chapter 16.)
-
- XXXX:0040303B DIV ECX ;ECX=1F4
- XXXX:0040303D MOVSX EDX,BYTE PTR [ESP+000003F0] ;from the keyfile
- XXXX:00403045 MOV [0040D1B8],EAX ;VV
- XXXX:0040304C JZ 0040305D ;we must jump
- ...
- XXXX:0040305D MOV DWORD PTR [0040D0B4],000000D
- XXXX:00403067 XOR EAX,EAX
- XXXX:00403069 POP EDI
- XXXX:0040306A POP ESI
- XXXX:0040306B POP EBX
- XXXX:0040306C ADD ESP,00000800
- XXXX:00403072 RET ;end of call 00402F70
-
-
- =================================================
- 19. PART 16/17 - CALL 00403080 (en XXXX:00401CF0)
- =================================================
-
-
- XXXX:00403127 MOV ECX,[0040D1B8] ;VV
- XXXX:0040312D ADD ECX,[0040D1B4] ;UU
- XXXX:00403133 ADD ECX,[0040D1B0] ;TT
- XXXX:00403139 ADD ECX,[0040D1AC] ;YY
- XXXX:0040313F ADD ECX,[0040D1A8] ;ZZ
- XXXX:00403145 MOV [ESP+18],ECX ;for me i have: DA
- XXXX:00403149 MOV DWORD PTR [ESP+1C],00000000
- XXXX:00403151 MOV QWORD PTR [ESP+18] ;on 64 bits
- XXXX:00403155 FSQRT ;square root (co-processor instruction)
- XXXX:00403157 CALL 0040420C ;result in EAX
- XXXX:0040315C MOVSX ECX,BYTE PTR [ESP+000003ED]
- XXXX:00403164 CMP EAX,ECX
- XXXX:00403166 JZ 00403173
- ...
- XXXX:00403173 MOV DWORD PTR [0040D0B4],0000000E
- XXXX:0040317D MOV EAX,00000001
- XXXX:00403182 POP EDI
- XXXX:00403183 POP ESI
- XXXX:00403184 ADD ESP,00000800
- XXXX:0040318A RET ;end of call 00403080
-
- An example: 0xDA = 218 and, sqrt(218)=14.7648... i round this to 14 (floor value):
- 0xE, it is the result found in EAX.
-
-
- Last icon!!!
-
-
- =================================================
- 20. PART 17/17 - CALL 00403080 (en XXXX:00401CF0)
- =================================================
-
- Last call, it's simple, it checks if the last character of the keyfile is "R".
-
- XXXX:00403237 CMP BYTE PTR [ESP+00000437],52 ;52 ("R")
- XXXX:0040323F JZ 0040324C
- ...
- XXXX:0040324C MOV DWORD PTR [0040D0B4],0000000F
- XXXX:00403256 MOV EAX,00000001
- XXXX:0040325B POP EDI
- XXXX:0040325C POP ESI
- XXXX:0040325D ADD ESP,00000800
- XXXX:00403263 RET ;end of call 00403080
-
- The end!!!!!!!!!!
-
- ==============
- 21. CONCLUSION
- ==============
-
- It took me a lot of time, to understand that the name was written at offset 9A (the 9Bth byte of
- the keyfile) and must be ended by a null byte. Otherwise, you will have some problems!!!
- In the call:
- 4. THE SURPRISE!
- 12. PART 09/17 - CALL 004028A0 (en XXXX:00401C8E)
- 13. PART 10/17 - CALL 004029A0 (en XXXX:00401C9C)
-
- This crackme is hard, but there are a lot a working keyfile.
-
- Lucifer48 (lucifer48@yahoo.com), 27 may 1999
-
- PS: When i thought again about it, it seems strange that we could manipulate the overflow of the
- stack, with a high-level language (such as C++). The instruction REPNZ SCASB should put me on the
- right way earlier. (on the beginning, i filled my keyfile with 33 bytes!!! ).
-
-